package com.dayu.tcp.common.compress;

import lombok.Getter;
import lombok.SneakyThrows;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class GzipCompression implements Compression {

    private GzipCompression() {
    }

    @Getter
    private static final GzipCompression instance = new GzipCompression();

    private final int unit = 2024;

    @Override
    @SneakyThrows
    public byte[] compress(byte[] src) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        GZIPOutputStream gzip = new GZIPOutputStream(byteArrayOutputStream);
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(src);

        try {
            byte[] buf = new byte[unit];
            int len;
            while ((len = byteArrayInputStream.read(buf)) != -1) {
                gzip.write(buf, 0, len);
            }
            gzip.finish();
            return byteArrayOutputStream.toByteArray();
        } finally {
            gzip.close();
            byteArrayOutputStream.close();
            byteArrayInputStream.close();
        }
    }

    @Override
    @SneakyThrows
    public byte[] decompress(byte[] src) {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(src);
        GZIPInputStream gzip = new GZIPInputStream(byteArrayInputStream);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            byte[] buf = new byte[unit];
            int len;
            while ((len = gzip.read(buf)) > 0) {
                byteArrayOutputStream.write(buf, 0, len);
            }
            return byteArrayOutputStream.toByteArray();
        } finally {
            gzip.close();
            byteArrayOutputStream.close();
            byteArrayInputStream.close();
        }
    }
}
